Assignment 3: Accessing Operational Data¶

Let's look at some operational data down in the Caribbean Sea during this year's Hurricane season. This joint meteorological and oceanographical effort in the Caribbean was first started in 2021; previous MOO student Casey Jones focused on this early effort for his thesis. Now years later, let's evaluate this crucial real-time data.¶

image.png

In [1]:
# First we begin with some imports
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import datetime
import cmocean.cm as cmo
import cartopy.crs as ccrs
import cool_maps.plot as cplt

How can we look at this data? MARACOOS OceansMap and IOOS GliderMap are two great sources and data portals. Let's look at some glider data first!¶

image.png

Now that we're on the ERDDAP > tabledap > Data Access Form, which variables do we need? There are a lot here, and we don't need all of them right now.¶

Let's uncheck everything first, then check just the ones we need!¶

Then we'll "Generate the URL" and paste that below¶

image.png

In [56]:
sg663  = 'https://gliders.ioos.us/erddap/tabledap/SG663-20240710T1312.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
sg663  = pd.read_csv(sg663, sep=',', skiprows=range(1,2), parse_dates = ['time'])
sg663
Out[56]:
time latitude longitude depth salinity temperature density
0 2024-07-10 13:16:13+00:00 18.337942 -69.635303 0.441536 NaN 29.681566 NaN
1 2024-07-10 13:16:13+00:00 18.337942 -69.635303 0.770287 NaN 29.681566 NaN
2 2024-07-10 13:16:13+00:00 18.337942 -69.635303 0.783423 NaN 29.681408 NaN
3 2024-07-10 13:16:13+00:00 18.337942 -69.635303 0.783299 NaN 29.676233 NaN
4 2024-07-10 13:16:13+00:00 18.337942 -69.635303 0.960860 NaN 29.680200 NaN
... ... ... ... ... ... ... ...
410771 2024-09-26 11:31:09+00:00 16.464665 -68.407257 3.534607 35.701324 30.376059 1022.12274
410772 2024-09-26 11:31:09+00:00 16.464665 -68.407257 2.402115 35.697620 30.381084 1022.11820
410773 2024-09-26 11:31:09+00:00 16.464665 -68.407257 1.441740 35.701443 30.382212 1022.12067
410774 2024-09-26 11:31:09+00:00 16.464665 -68.407257 0.295104 NaN 30.384502 1022.11780
410775 2024-09-26 11:31:09+00:00 16.464665 -68.407257 -0.001601 NaN 30.312267 NaN

410776 rows × 7 columns

Let's plot the data to see if we pulled the right glider. So let's visualize it on a cool_maps map, and have the colorbar indicate time.¶

In [7]:
# First we set the extent
extent = [-70.5, -62, 14.5, 24.5]

# Then create our cool_maps figure
fig,axs   = cplt.create(extent, proj=ccrs.Mercator(), bathymetry=True, isobaths=(-1000, -10), figsize=(10,6), oceancolor='w')

# Then plot our data onto the figure
ax_sg663 = plt.scatter(sg663['longitude'],sg663['latitude'],c=sg663['time'], marker="o", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())

# Date colorbar code taken from: https://stackoverflow.com/questions/51160705/plot-time-series-with-colorbar-in-pandas-matplotlib
# Define your mappable for colorbar creation
sm = plt.cm.ScalarMappable(cmap='cool', 
                           norm=plt.Normalize(vmin=sg663['time'].min().value,
                                              vmax=sg663['time'].max().value));
# Add the colorbar
sm._A = [];
cbar = plt.colorbar(sm, ax = axs);

# Change the numeric ticks into ones that match. Time format options detailed here: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior
cbar.ax.set_yticklabels(pd.to_datetime(cbar.get_ticks()).strftime(date_format='%b %d'));
No description has been provided for this image

Look's good!¶

How about looking at some Saildrone data? If we check OceansMap, we can turn on this year's Hurricane Saildrone layer.¶

If we want to access the data, we can click the little i for more information, and follow the link to the ERDDAP page.¶

image.png

That takes us to the MARACOOS ERDDAP page that serves all the data the OceansMap visualizes. You'll often find the data on multiple ERDDAP pages, like this NOAA one from PMEL, which may serve it for longer than the MARACOOS one. For now, let's use the MARACOOS page. Since there aren't a lot of variables, let's leave them all checked and generate the URL. Since we're not being selective with the variables, we can remove everything after the .csv in the URL if we want a cleaner look.¶

In [65]:
sd1041  = 'https://erddap.maracoos.org/erddap/tabledap/sd1041_hurricane_2024.csv'
sd1041  = pd.read_csv(sd1041, sep=',', skiprows=range(1,2), parse_dates = ['time'])
sd1041
Out[65]:
latitude longitude time trajectory TEMP_AIR_MEAN RH_MEAN BARO_PRES_MEAN TEMP_SBE37_MEAN WIND_FROM_MEAN WIND_SPEED_MEAN SAL_SBE37_MEAN WAVE_DOMINANT_PERIOD WAVE_SIGNIFICANT_HEIGHT
0 18.233480 -64.779853 2024-06-25 14:00:00+00:00 1041.0 29.63 80.79 1016.71 29.8179 98.2 9.07 36.3313 6.10 1.598
1 18.234176 -64.779904 2024-06-25 14:01:00+00:00 1041.0 29.60 80.89 1016.70 29.8168 99.4 8.80 36.3313 6.10 1.593
2 18.234829 -64.779923 2024-06-25 14:02:00+00:00 1041.0 29.61 81.66 1016.68 29.8158 100.6 8.76 36.3324 6.10 1.590
3 18.235451 -64.780032 2024-06-25 14:03:00+00:00 1041.0 29.61 81.98 1016.68 29.8157 94.9 8.47 36.3309 6.10 1.593
4 18.236083 -64.780102 2024-06-25 14:04:00+00:00 1041.0 29.61 81.59 1016.67 29.8156 93.6 8.71 36.3314 6.10 1.584
... ... ... ... ... ... ... ... ... ... ... ... ... ...
135115 18.878843 -67.258573 2024-09-26 21:55:00+00:00 1041.0 30.32 78.27 1012.04 30.6961 90.8 7.44 35.9019 10.67 1.409
135116 18.879126 -67.258541 2024-09-26 21:56:00+00:00 1041.0 NaN NaN NaN NaN 81.1 7.47 NaN 10.67 1.418
135117 18.879459 -67.258541 2024-09-26 21:57:00+00:00 1041.0 NaN NaN NaN NaN 79.0 7.42 NaN 10.67 1.432
135118 18.879757 -67.258579 2024-09-26 21:58:00+00:00 1041.0 NaN NaN NaN NaN 80.9 7.68 NaN 10.67 1.443
135119 18.880131 -67.258579 2024-09-26 21:59:00+00:00 1041.0 NaN NaN NaN NaN 86.8 6.78 NaN 10.67 1.456

135120 rows × 13 columns

Now let's repeat the same mapping process we did above, but for the saildrone this time.¶

In [113]:
# First we set the extent
extent = [-70.5, -62, 14.5, 24.5]

# Then create our cool_maps figure
fig,axs   = cplt.create(extent, proj=ccrs.Mercator(), bathymetry=True, isobaths=(-1000, -10), figsize=(10,6), oceancolor='w')

# Then plot our data onto the figure
ax_sd1041 = plt.scatter(sd1041['longitude'],sd1041['latitude'],c=sd1041['time'], marker="o", edgecolors='none',cmap='cool', alpha = .2, transform=ccrs.PlateCarree())

# Date colorbar code taken from: https://stackoverflow.com/questions/51160705/plot-time-series-with-colorbar-in-pandas-matplotlib
# Define your mappable for colorbar creation
sm = plt.cm.ScalarMappable(cmap='cool', 
                           norm=plt.Normalize(vmin=sd1041['time'].min().value,
                                              vmax=sd1041['time'].max().value));
# Add the colorbar
sm._A = [];
cbar = plt.colorbar(sm, ax = axs);

# Change the numeric ticks into ones that match. Time format options detailed here: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior
cbar.ax.set_yticklabels(pd.to_datetime(cbar.get_ticks()).strftime(date_format='%b %d'));
No description has been provided for this image

Looks good!¶

Now that you've accessed the data, let's begin the assignment!¶

Once complete, File > Save and Export Notebook As... > HTML and upload your html file to Canvas.¶

1. Using the following URLs for the other saildrones & gliders, load in all of the datasets as done above.¶

In [80]:
sg649  = 'https://gliders.ioos.us/erddap/tabledap/SG649-20240712T1133.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
sg649  = pd.read_csv(sg649, sep=',', skiprows=range(1,2), parse_dates = ['time'])
sg649
Out[80]:
time latitude longitude depth salinity temperature density
0 2024-07-12 11:37:53+00:00 18.463570 -67.304019 0.617856 NaN 29.697739 NaN
1 2024-07-12 11:37:53+00:00 18.463570 -67.304019 0.800471 NaN 29.699413 NaN
2 2024-07-12 11:37:53+00:00 18.463570 -67.304019 0.771923 NaN 29.701405 NaN
3 2024-07-12 11:37:53+00:00 18.463570 -67.304019 0.911291 NaN 29.703192 NaN
4 2024-07-12 11:37:53+00:00 18.463570 -67.304019 0.933263 NaN 29.703768 NaN
... ... ... ... ... ... ... ...
404217 2024-09-26 22:17:33+00:00 18.960283 -65.823707 3.343639 35.458070 30.480658 1021.9043
404218 2024-09-26 22:17:33+00:00 18.960283 -65.823707 1.995474 35.456306 30.482527 1021.9023
404219 2024-09-26 22:17:33+00:00 18.960283 -65.823707 0.838080 NaN 30.477050 1021.9044
404220 2024-09-26 22:17:33+00:00 18.960283 -65.823707 -0.067845 NaN 30.463682 NaN
404221 2024-09-26 22:17:33+00:00 18.960283 -65.823707 -0.230565 NaN 30.388618 NaN

404222 rows × 7 columns

In [57]:
# Saildrones from http://erddap.maracoos.org/erddap/search/index.html?page=1&itemsPerPage=1000&searchFor=Saildrone%20Atlantic%202024
sd1031  = 'http://erddap.maracoos.org/erddap/tabledap/sd1031_hurricane_2024.csv'
sd1031  = pd.read_csv(sd1031, sep=',', skiprows=range(1,2), parse_dates = ['time'])

sd1041  = 'http://erddap.maracoos.org/erddap/tabledap/sd1041_hurricane_2024.csv'
sd1041  = pd.read_csv(sd1041, sep=',', skiprows=range(1,2), parse_dates = ['time'])

sd1036  = 'http://erddap.maracoos.org/erddap/tabledap/sd1036_hurricane_2024.csv'
sd1036  = pd.read_csv(sd1036, sep=',', skiprows=range(1,2), parse_dates = ['time'])

sd1040  = 'http://erddap.maracoos.org/erddap/tabledap/sd1040_hurricane_2024.csv'
sd1040  = pd.read_csv(sd1040, sep=',', skiprows=range(1,2), parse_dates = ['time'])

sd1057  = 'http://erddap.maracoos.org/erddap/tabledap/sd1057_hurricane_2024.csv'
sd1057  = pd.read_csv(sd1057, sep=',', skiprows=range(1,2), parse_dates = ['time'])

sd1068  = 'http://erddap.maracoos.org/erddap/tabledap/sd1068_hurricane_2024.csv'
sd1068  = pd.read_csv(sd1068, sep=',', skiprows=range(1,2), parse_dates = ['time'])

sd1069  = 'http://erddap.maracoos.org/erddap/tabledap/sd1069_hurricane_2024.csv'
sd1069  = pd.read_csv(sd1069, sep=',', skiprows=range(1,2), parse_dates = ['time'])

sd1083  = 'http://erddap.maracoos.org/erddap/tabledap/sd1083_hurricane_2024.csv'
sd1083  = pd.read_csv(sd1083, sep=',', skiprows=range(1,2), parse_dates = ['time'])

sd1091  = 'http://erddap.maracoos.org/erddap/tabledap/sd1091_hurricane_2024.csv'
sd1091  = pd.read_csv(sd1091, sep=',', skiprows=range(1,2), parse_dates = ['time'])

# Gliders from https://gliders.ioos.us/erddap/tabledap/index.html?page=1&itemsPerPage=1000 	
ng278  = 'https://gliders.ioos.us/erddap/tabledap/ng278-20240711T0000.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
ng278  = pd.read_csv(ng278, sep=',', skiprows=range(1,2), parse_dates = ['time'])

ng656  = 'https://gliders.ioos.us/erddap/tabledap/ng656-20240613T0000.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
ng656  = pd.read_csv(ng656, sep=',', skiprows=range(1,2), parse_dates = ['time'])

ng783  = 'https://gliders.ioos.us/erddap/tabledap/ng783-20240807T0000.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
ng783  = pd.read_csv(ng783, sep=',', skiprows=range(1,2), parse_dates = ['time'])

ng738  = 'https://gliders.ioos.us/erddap/tabledap/ng738-20240807T0000.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
ng738  = pd.read_csv(ng738, sep=',', skiprows=range(1,2), parse_dates = ['time'])

sg663  = 'https://gliders.ioos.us/erddap/tabledap/SG663-20240710T1312.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
sg663  = pd.read_csv(sg663, sep=',', skiprows=range(1,2), parse_dates = ['time'])

sg678  = 'https://gliders.ioos.us/erddap/tabledap/SG678-20240617T1202.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
sg678  = pd.read_csv(sg678, sep=',', skiprows=range(1,2), parse_dates = ['time'])

sg630  = 'https://gliders.ioos.us/erddap/tabledap/SG630-20240713T1103.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
sg630  = pd.read_csv(sg630, sep=',', skiprows=range(1,2), parse_dates = ['time'])

sg610  = 'https://gliders.ioos.us/erddap/tabledap/SG610-20240711T1133.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
sg610  = pd.read_csv(sg610, sep=',', skiprows=range(1,2), parse_dates = ['time'])

sg649  = 'https://gliders.ioos.us/erddap/tabledap/SG649-20240712T1133.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
sg649  = pd.read_csv(sg649, sep=',', skiprows=range(1,2), parse_dates = ['time'])

2A. Create a single, large map like above including all the 9 saildrone and 9 glider tracks, with each colored by time.¶

In [83]:
# First we set the extent
extent = [-85, -50, 14.5, 34]

# Then create our cool_maps figure
fig,axs   = cplt.create(extent, proj=ccrs.Mercator(), bathymetry=True, isobaths=(-1000, -10), figsize=(10,6), oceancolor='w')

# Then plot our data onto the figure
ax_ng278 = plt.scatter(ng278['longitude'],ng278['latitude'],c=ng278['time'], marker="o", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_ng656 = plt.scatter(ng656['longitude'],ng656['latitude'],c=ng656['time'], marker="o", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_ng783 = plt.scatter(ng783['longitude'],ng783['latitude'],c=ng783['time'], marker="o", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_ng738 = plt.scatter(ng738['longitude'],ng738['latitude'],c=ng738['time'], marker="o", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sg663 = plt.scatter(sg663['longitude'],sg663['latitude'],c=sg663['time'], marker="o", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sg678 = plt.scatter(sg678['longitude'],sg678['latitude'],c=sg678['time'], marker="o", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sg630 = plt.scatter(sg630['longitude'],sg630['latitude'],c=sg630['time'], marker="o", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sg610 = plt.scatter(sg610['longitude'],sg610['latitude'],c=sg610['time'], marker="o", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sg649 = plt.scatter(sg649['longitude'],sg649['latitude'],c=sg649['time'], marker="o", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())

ax_sd1031 = plt.scatter(sd1031['longitude'],sd1031['latitude'],c=sd1031['time'], marker="x", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sd1041 = plt.scatter(sd1041['longitude'],sd1041['latitude'],c=sd1041['time'], marker="x", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sd1036 = plt.scatter(sd1036['longitude'],sd1036['latitude'],c=sd1036['time'], marker="x", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sd1040 = plt.scatter(sd1040['longitude'],sd1040['latitude'],c=sd1040['time'], marker="x", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sd1057 = plt.scatter(sd1057['longitude'],sd1057['latitude'],c=sd1057['time'], marker="x", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sd1068 = plt.scatter(sd1068['longitude'],sd1068['latitude'],c=sd1068['time'], marker="x", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sd1069 = plt.scatter(sd1069['longitude'],sd1069['latitude'],c=sd1069['time'], marker="x", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sd1083 = plt.scatter(sd1083['longitude'],sd1083['latitude'],c=sd1083['time'], marker="x", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sd1091 = plt.scatter(sd1091['longitude'],sd1091['latitude'],c=sd1091['time'], marker="x", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())

# Date colorbar code taken from: https://stackoverflow.com/questions/51160705/plot-time-series-with-colorbar-in-pandas-matplotlib
# Define your mappable for colorbar creation
sm = plt.cm.ScalarMappable(cmap='cool', 
                           norm=plt.Normalize(vmin=ng278['time'].min().value,
                                              vmax=sg649['time'].max().value));
# Add the colorbar
sm._A = [];
cbar = plt.colorbar(sm, ax = axs);

# Change the numeric ticks into ones that match. Time format options detailed here: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior
cbar.ax.set_yticklabels(pd.to_datetime(cbar.get_ticks()).strftime(date_format='%b %d'));

fig.text(0.5, 0.01, "Figure 1: Map compiling all glider and saildron missions in specific location. Saildrones are marked with an (x) where  gliders are marked with (o)", ha='center')
Out[83]:
Text(0.5, 0.01, 'Figure 1: Map compiling all glider and saildron missions in specific location. Saildrones are marked with an (x) where  gliders are marked with (o)')
No description has been provided for this image

2B. Caption the figure, describing the key takeaways.¶

see above¶

3A. Plot a figure with 9 x 2 subplots, showing temperature for each of the 18 platforms. Use xlim to align the subplots in time. The 9 saildrone plots should be air temperature by time, with the markers colored by water temperature. The 9 glider plots should be depth by time, with the markers colored by water temperature. Be sure to add a colorbar and labels when appropriate.¶

In [110]:
import matplotlib.dates as mdates
In [112]:
fig, axs = plt.subplots(9, 2, figsize=(7, 20))
xlim_start = pd.to_datetime('2024-05-25')
xlim_end = pd.to_datetime('2024-09-30')

# Saildrone plots (air temp vs. time, colored by water temp)
sc1 = axs[0, 0].scatter(sd1031['time'], sd1031['TEMP_AIR_MEAN'], c=sd1031['TEMP_SBE37_MEAN'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc1, ax=axs[0, 0])
axs[0, 0].set_title('Saildrone 1031')
axs[0, 0].set_xlabel('Time')
axs[0, 0].set_ylabel('Air Temperature[°C]')
axs[0, 0].set_xlim([xlim_start, xlim_end])


axs[0, 0].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))  
axs[0, 0].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d'))  

sc2 = axs[1, 0].scatter(sd1041['time'], sd1041['TEMP_AIR_MEAN'], c=sd1041['TEMP_SBE37_MEAN'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc2, ax=axs[1, 0])
axs[1, 0].set_title('Saildrone 1041')
axs[1, 0].set_xlabel('Time')
axs[1, 0].set_ylabel('Air Temperature[°C]')
axs[1, 0].set_xlim([xlim_start, xlim_end])


axs[1, 0].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))  
axs[1, 0].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d')) 

sc3 = axs[2, 0].scatter(sd1036['time'], sd1036['TEMP_AIR_MEAN'], c=sd1036['TEMP_SBE37_MEAN'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc3, ax=axs[2, 0])
axs[2, 0].set_title('Saildrone 1036')
axs[2, 0].set_xlabel('Time')
axs[2, 0].set_ylabel('Air Temperature[°C]')
axs[2, 0].set_xlim([xlim_start, xlim_end])


axs[2, 0].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))  
axs[2, 0].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d')) 

sc4 = axs[3, 0].scatter(sd1040['time'], sd1040['TEMP_AIR_MEAN'], c=sd1040['TEMP_SBE37_MEAN'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc4, ax=axs[3, 0])
axs[3, 0].set_title('Saildrone 1040')
axs[3, 0].set_xlabel('Time')
axs[3, 0].set_ylabel('Air Temperature[°C]')
axs[3, 0].set_xlim([xlim_start, xlim_end])


axs[3, 0].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))  
axs[3, 0].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d')) 

sc5 = axs[4, 0].scatter(sd1057['time'], sd1057['TEMP_AIR_MEAN'], c=sd1057['TEMP_SBE37_MEAN'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc5, ax=axs[4, 0])
axs[4, 0].set_title('Saildrone 1057')
axs[4, 0].set_xlabel('Time')
axs[4, 0].set_ylabel('Air Temperature[°C]')
axs[4, 0].set_xlim([xlim_start, xlim_end])


axs[4, 0].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))  
axs[4, 0].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d')) 

sc6 = axs[5, 0].scatter(sd1068['time'], sd1068['TEMP_AIR_MEAN'], c=sd1068['TEMP_SBE37_MEAN'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc6, ax=axs[5, 0])
axs[5, 0].set_title('Saildrone 1068')
axs[5, 0].set_xlabel('Time')
axs[5, 0].set_ylabel('Air Temperature[°C]')
axs[5, 0].set_xlim([xlim_start, xlim_end])


axs[5, 0].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))  
axs[5, 0].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d')) 

sc7 = axs[6, 0].scatter(sd1069['time'], sd1069['TEMP_AIR_MEAN'], c=sd1069['TEMP_SBE37_MEAN'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc7, ax=axs[6, 0])
axs[6, 0].set_title('Saildrone 1069')
axs[6, 0].set_xlabel('Time')
axs[6, 0].set_ylabel('Air Temperature[°C]')
axs[6, 0].set_xlim([xlim_start, xlim_end])


axs[6, 0].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))  
axs[6, 0].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d')) 

sc8 = axs[7, 0].scatter(sd1083['time'], sd1083['TEMP_AIR_MEAN'], c=sd1083['TEMP_SBE37_MEAN'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc8, ax=axs[7, 0])
axs[7, 0].set_title('Saildrone 1083')
axs[7, 0].set_xlabel('Time')
axs[7, 0].set_ylabel('Air Temperature[°C]')
axs[7, 0].set_xlim([xlim_start, xlim_end])


axs[7, 0].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))  
axs[7, 0].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d')) 

sc9 = axs[8, 0].scatter(sd1091['time'], sd1091['TEMP_AIR_MEAN'], c=sd1091['TEMP_SBE37_MEAN'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc9, ax=axs[8, 0])
axs[8, 0].set_title('Saildrone 1091')
axs[8, 0].set_xlabel('Time')
axs[8, 0].set_ylabel('Air Temperature[°C]')
axs[8, 0].set_xlim([xlim_start, xlim_end])


axs[8, 0].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))  
axs[8, 0].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d')) 

# Glider plots (depth vs. time, colored by water temperature)
sc10 = axs[0, 1].scatter(ng278['time'], ng278['depth'], c=ng278['temperature'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc10, ax=axs[0, 1])
axs[0, 1].invert_yaxis()
axs[0, 1].set_title('Glider 278')
axs[0, 1].set_xlabel('Time')
axs[0, 1].set_ylabel('Depth[m]')
axs[0, 1].set_xlim([xlim_start, xlim_end])


axs[0, 1].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))  
axs[0, 1].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d')) 

sc11 = axs[1, 1].scatter(ng656['time'], ng656['depth'], c=ng656['temperature'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc11, ax=axs[1, 1])
axs[1, 1].invert_yaxis()
axs[1, 1].set_title('Glider 656')
axs[1, 1].set_xlabel('Time')
axs[1, 1].set_ylabel('Depth[m]')
axs[1, 1].set_xlim([xlim_start, xlim_end])


axs[1, 1].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))  
axs[1, 1].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d')) 

sc12 = axs[2, 1].scatter(ng783['time'], ng783['depth'], c=ng783['temperature'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc12, ax=axs[2, 1])
axs[2, 1].invert_yaxis()
axs[2, 1].set_title('Glider 783')
axs[2, 1].set_xlabel('Time')
axs[2, 1].set_ylabel('Depth[m]')
axs[2, 1].set_xlim([xlim_start, xlim_end])


axs[2, 1].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))  
axs[2, 1].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d')) 

sc13 = axs[3, 1].scatter(ng738['time'], ng738['depth'], c=ng738['temperature'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc13, ax=axs[3, 1])
axs[3, 1].invert_yaxis()
axs[3, 1].set_title('Glider 738')
axs[3, 1].set_xlabel('Time')
axs[3, 1].set_ylabel('Depth[m]')
axs[3, 1].set_xlim([xlim_start, xlim_end])


axs[3, 1].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))  
axs[3, 1].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d')) 

sc14 = axs[4, 1].scatter(sg663['time'], sg663['depth'], c=sg663['temperature'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc14, ax=axs[4, 1])
axs[4, 1].invert_yaxis()
axs[4, 1].set_title('Glider 663')
axs[4, 1].set_xlabel('Time')
axs[4, 1].set_ylabel('Depth[m]')
axs[4, 1].set_xlim([xlim_start, xlim_end])


axs[4, 1].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))  
axs[4, 1].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d')) 

sc15 = axs[5, 1].scatter(sg678['time'], sg678['depth'], c=sg678['temperature'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc15, ax=axs[5, 1])
axs[5, 1].invert_yaxis()
axs[5, 1].set_title('Glider 678')
axs[5, 1].set_xlabel('Time')
axs[5, 1].set_ylabel('Depth[m]')
axs[5, 1].set_xlim([xlim_start, xlim_end])


axs[5, 1].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))  
axs[5, 1].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d')) 

sc16 = axs[6, 1].scatter(sg630['time'], sg630['depth'], c=sg630['temperature'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc16, ax=axs[6, 1])
axs[6, 1].invert_yaxis()
axs[6, 1].set_title('Glider 630')
axs[6, 1].set_xlabel('Time')
axs[6, 1].set_ylabel('Depth[m]')
axs[6, 1].set_xlim([xlim_start, xlim_end])


axs[6, 1].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))  
axs[6, 1].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d')) 

sc17 = axs[7, 1].scatter(sg610['time'], sg610['depth'], c=sg610['temperature'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc17, ax=axs[7, 1])
axs[7, 1].invert_yaxis()
axs[7, 1].set_title('Glider 610')
axs[7, 1].set_xlabel('Time')
axs[7, 1].set_ylabel('Depth[m]')
axs[7, 1].set_xlim([xlim_start, xlim_end])


axs[7, 1].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))  
axs[7, 1].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d')) 

sc18 = axs[8, 1].scatter(sg649['time'], sg649['depth'], c=sg649['temperature'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc18, ax=axs[8, 1])
axs[8, 1].invert_yaxis()
axs[8, 1].set_title('Glider 649')
axs[8, 1].set_xlabel('Time')
axs[8, 1].set_ylabel('Depth[m]')
axs[8, 1].set_xlim([xlim_start, xlim_end])


axs[8, 1].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))  
axs[8, 1].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d')) 


for ax in axs.flat:
    plt.setp(ax.get_xticklabels(), rotation=45, ha='right')
    
#x_limits = [pd.Timestamp("2024-05-20"),pd.Timestamp("2024-09-30")]
#for ax in axs.flat:
    #ax.set_xlim(x_limits)
fig.text(0.5, 0.001, "Figure 2: Left plots map out air temp vs time compared to sea surface temp of saildrones. Right side shows depth vs time compared to sea temp", ha='center')
plt.tight_layout()
plt.show()

#
No description has been provided for this image
In [114]:
#Highlights the difference in air temp to water temp for saildrones and shows temperature over depth for gliders. Allows for higher acuracy surface temps and detailed sea temps at depth for water columns. 

4A. Plot the wind speed by the pressure, colored by wave height, for the saildrone plots as separate subplots.¶

In [101]:
fig, axs = plt.subplots(9, 1, figsize=(7, 20))

# Saildrone plots (air temp vs. time, colored by water temp)
sc1 = axs[0,].scatter(sd1031['BARO_PRES_MEAN'], sd1031['WIND_SPEED_MEAN'], c=sd1031['WAVE_SIGNIFICANT_HEIGHT'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc1, ax=axs[0,])
axs[0, ].set_title('Saildrone 1031')
axs[0, ].set_xlabel('Pressure')
axs[0, ].set_ylabel('Wind Speed')

sc2 = axs[1, ].scatter(sd1041['BARO_PRES_MEAN'], sd1041['WIND_SPEED_MEAN'], c=sd1041['WAVE_SIGNIFICANT_HEIGHT'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc2, ax=axs[1,])
axs[1, ].set_title('Saildrone 1041')
axs[1, ].set_xlabel('Pressure')
axs[1, ].set_ylabel('Wind Speed')

sc3 = axs[2, ].scatter(sd1036['BARO_PRES_MEAN'], sd1036['WIND_SPEED_MEAN'], c=sd1036['WAVE_SIGNIFICANT_HEIGHT'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc3, ax=axs[2, ])
axs[2, ].set_title('Saildrone 1036')
axs[2, ].set_xlabel('Pressure')
axs[2, ].set_ylabel('Wind Speed')

sc4 = axs[3, ].scatter(sd1040['BARO_PRES_MEAN'], sd1040['WIND_SPEED_MEAN'], c=sd1040['WAVE_SIGNIFICANT_HEIGHT'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc4, ax=axs[3, ])
axs[3, ].set_title('Saildrone 1040')
axs[3, ].set_xlabel('Pressure')
axs[3, ].set_ylabel('Wind Speed')

sc5 = axs[4, ].scatter(sd1057['BARO_PRES_MEAN'], sd1057['WIND_SPEED_MEAN'], c=sd1057['WAVE_SIGNIFICANT_HEIGHT'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc5, ax=axs[4, ])
axs[4, ].set_title('Saildrone 1057')
axs[4, ].set_xlabel('Pressure')
axs[4, ].set_ylabel('Wind Speed')

sc6 = axs[5, ].scatter(sd1068['BARO_PRES_MEAN'], sd1068['WIND_SPEED_MEAN'], c=sd1068['WAVE_SIGNIFICANT_HEIGHT'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc6, ax=axs[5,])
axs[5, ].set_title('Saildrone 1068')
axs[5, ].set_xlabel('Pressure')
axs[5, ].set_ylabel('Wind Speed')

sc7 = axs[6, ].scatter(sd1069['BARO_PRES_MEAN'], sd1069['WIND_SPEED_MEAN'], c=sd1069['WAVE_SIGNIFICANT_HEIGHT'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc7, ax=axs[6, ])
axs[6, ].set_title('Saildrone 1069')
axs[6, ].set_xlabel('Pressure')
axs[6, ].set_ylabel('Wind Speed')

sc8 = axs[7, ].scatter(sd1083['BARO_PRES_MEAN'], sd1083['WIND_SPEED_MEAN'], c=sd1083['WAVE_SIGNIFICANT_HEIGHT'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc8, ax=axs[7, ])
axs[7, ].set_title('Saildrone 1083')
axs[7, ].set_xlabel('Pressure')
axs[7, ].set_ylabel('Wind Speed')

sc9 = axs[8, ].scatter(sd1091['BARO_PRES_MEAN'], sd1091['WIND_SPEED_MEAN'], c=sd1091['WAVE_SIGNIFICANT_HEIGHT'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc9, ax=axs[8, ])
axs[8, ].set_title('Saildrone 1091')
axs[8, ].set_xlabel('Pressure')
axs[8, ].set_ylabel('Wind Speed')


x_limits = [950,1030] 
for ax in axs.flat:
    ax.set_xlim(x_limits)

fig.text(0.5, 0.001, "Figure 3: wind speed vs pressure compared to wave hights for saildrones", ha='center')
plt.tight_layout()
plt.show()
No description has been provided for this image

4B. Caption the figure, describing the key takeaways.¶

Higher wind speed leads to increased wave heights. Increased pressure leads to slower wind and shorter waves.¶

5A. Plot TS diagrams, colored by density, for the 9 gliders as separate subplots.¶

In [106]:
fig, axs = plt.subplots(9, 1, figsize=(7, 20))
sc10 = axs[0, ].scatter(ng278['salinity'], ng278['temperature'], c=ng278['density'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc10, ax=axs[0, ])

axs[0,].set_title('Glider 278')
axs[0,].set_xlabel('Salinity [PSU]')
axs[0,].set_ylabel('Temperature [°C]')

sc11 = axs[1,].scatter(ng656['salinity'], ng656['temperature'], c=ng656['density'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc11, ax=axs[1, ])

axs[1, ].set_title('Glider 656')
axs[1, ].set_xlabel('Salinity [PSU]')
axs[1, ].set_ylabel('Temperature [°C]')

sc12 = axs[2, ].scatter(ng783['salinity'], ng783['temperature'], c=ng783['density'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc12, ax=axs[2, ])

axs[2, ].set_title('Glider 783')
axs[2, ].set_xlabel('Salinity [PSU]')
axs[2, ].set_ylabel('Temperature [°C]')

sc13 = axs[3, ].scatter(ng738['salinity'], ng738['temperature'], c=ng738['density'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc13, ax=axs[3, ])

axs[3, ].set_title('Glider 738')
axs[3, ].set_xlabel('Salinity [PSU]')
axs[3, ].set_ylabel('Temperature [°C]')

sc14 = axs[4, ].scatter(sg663['salinity'], sg663['temperature'], c=sg663['density'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc14, ax=axs[4, ])

axs[4, ].set_title('Glider 663')
axs[4, ].set_xlabel('Salinity [PSU]')
axs[4, ].set_ylabel('Temperature [°C]')

sc15 = axs[5, ].scatter(sg678['salinity'], sg678['temperature'], c=sg678['density'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc15, ax=axs[5, ])

axs[5, ].set_title('Glider 678')
axs[5, ].set_xlabel('Salinity [PSU]')
axs[5, ].set_ylabel('Temperature [°C]')

sc16 = axs[6, ].scatter(sg630['salinity'], sg630['temperature'], c=sg630['density'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc16, ax=axs[6, ])

axs[6, ].set_title('Glider 630')
axs[6, ].set_xlabel('Salinity [PSU]')
axs[6, ].set_ylabel('Temperature [°C]')

sc17 = axs[7, ].scatter(sg610['salinity'], sg610['temperature'], c=sg610['density'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc17, ax=axs[7, ])

axs[7, ].set_title('Glider 610')
axs[7, ].set_xlabel('Salinity [PSU]')
axs[7, ].set_ylabel('Temperature [°C]')

sc18 = axs[8, ].scatter(sg649['salinity'], sg649['temperature'], c=sg649['density'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc18, ax=axs[8, ])

axs[8, ].set_title('Glider 649')
axs[8, ].set_xlabel('Salinity [PSU]')
axs[8, ].set_ylabel('Temperature [°C]')

x_limits = [33.3,38.5]
for ax in axs.flat:
    ax.set_xlim(x_limits)
fig.text(0.5, 0.001, "Figure 4: Temp vs salinity compared to density for gliders", ha='center')
plt.tight_layout()
plt.show()
No description has been provided for this image

5B. Caption the figure, describing the key takeaways.¶

Higher temp of water linked to lower density levels. Salinity peak around mid point of tempurature range. Highest density at coolest tempurature and roughly 35 psu salinity.¶

6. What overall insights and conclusions can you synthesize from evaluating the data from these saildrones and gliders?¶

It is interesting to see how the plots are formed from two differnt systems. While some of the data is from different locations you can see similarities in tempurature readings. Each system collects different samples which is used to produce more detailed images of bodies of water. The range of data that can be collected is also increased.¶

In [ ]: